<template>
    <div class="vehicle-add-page">
        <div class="page-title">新增车辆</div>

        <div class="form card">
            <div class="grid">
                <div class="form-item required">
                    <label class="label">厂牌型号：</label>
                    <input class="input" v-model.trim="form.brandModel" placeholder="请输入厂牌型号" />
                </div>

                <div class="form-item required">
                    <label class="label">车辆类型：</label>
                    <select class="input" v-model="form.vehicleType">
                        <option value="" disabled>请选择车辆类型</option>
                        <option value="冷冻车">冷冻车</option>
                        <option value="货车">货车</option>
                        <option value="前四后八">前四后八</option>
                    </select>
                </div>

                <div class="form-item required">
                    <label class="label">车牌号：</label>
                    <input class="input" v-model.trim="form.plateNumber" placeholder="请输入车牌号" />
                </div>



                <div class="form-item required">
                    <label class="label">司机姓名：</label>
                    <select class="input" v-model="form.driverName" @change="onDriverChange">
                        <option value="" disabled>请选择司机（货主）</option>
                        <option v-for="o in ownerOptions" :key="o.id" :value="o.ownerName">{{ o.ownerName }}</option>
                    </select>
                </div>

                <div class="form-item required">
                    <label class="label">所属公司：</label>
                    <select class="input" v-model="form.company">
                        <option value="" disabled>请选择所属公司</option>
                        <option v-for="c in companyOptions" :key="c" :value="c">{{ c }}</option>
                    </select>
                </div>

                <div class="form-item required size-group">
                    <label class="label">车 型：</label>
                    <input class="input size" type="text" v-model.trim="form.sizeLength" placeholder="长" />
                    <input class="input size" type="text" v-model.trim="form.sizeWidth" placeholder="宽" />
                    <input class="input size" type="text" v-model.trim="form.sizeHeight" placeholder="高" />
                </div>

                <div class="form-item required">
                    <label class="label">车辆颜色：</label>
                    <input class="input" v-model.trim="form.color" placeholder="请输入车辆颜色" />
                </div>

                <div class="form-item required">
                    <label class="label">购置日期：</label>
                    <input class="input" type="date" v-model="form.purchaseDate" placeholder="请选择购置日期" />
                </div>

                <div class="form-item required">
                    <label class="label">营运证号：</label>
                    <input class="input" v-model.trim="form.operationCert" placeholder="请输入营运证号" />
                </div>

                <div class="form-item required">
                    <label class="label">保险到期日期：</label>
                    <input class="input" type="date" v-model="form.insuranceExpire" placeholder="请选择保险到期日期" />
                </div>

                <div class="form-item required">
                    <label class="label">年检到期日期：</label>
                    <input class="input" type="date" v-model="form.annualInspectExpire" placeholder="请选择年检到期日期" />
                </div>

                <div class="form-item">
                    <label class="label">保养公里数设置：</label>
                    <input class="input" v-model.trim="form.maintenanceKm" placeholder="请输入保养公里数" />
                </div>

                <div class="form-item upload-item">
                    <label class="label">车辆照片：</label>
                    <div class="upload-box" @click="triggerVehicleInput">
                        <input ref="vehicleInput" class="file-input" type="file" accept="image/*"
                            @change="onVehicleImg" />
                        <div v-if="!vehiclePreview" class="uploader">
                            <div class="plus">+</div>
                            <div class="text">上传图片</div>
                        </div>
                        <img v-else :src="vehiclePreview" class="preview" alt="vehicle" />
                        <div class="upload-meta">
                            <div v-if="vehicleUploadState === 'uploading'">上传中 {{ vehicleUploadPercent }}%</div>
                            <div v-else-if="vehicleUploadState === 'failed'">
                                上传失败 <a href="javascript:void(0)" @click.stop.prevent="retryVehicleUpload">重试</a>
                            </div>
                            <div v-else-if="vehicleUploadState === 'success'">已上传</div>
                        </div>
                    </div>
                </div>

                <div class="form-item upload-item">
                    <label class="label">保险卡照片：</label>
                    <div class="upload-box" @click="triggerInsureInput">
                        <input ref="insureInput" class="file-input" type="file" accept="image/*"
                            @change="onInsureImg" />
                        <div v-if="!insurePreview" class="uploader">
                            <div class="plus">+</div>
                            <div class="text">上传图片</div>
                        </div>
                        <img v-else :src="insurePreview" class="preview" alt="insure" />
                        <div class="upload-meta">
                            <div v-if="insureUploadState === 'uploading'">上传中 {{ insureUploadPercent }}%</div>
                            <div v-else-if="insureUploadState === 'failed'">
                                上传失败 <a href="javascript:void(0)" @click.stop.prevent="retryInsureUpload">重试</a>
                            </div>
                            <div v-else-if="insureUploadState === 'success'">已上传</div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="form-actions">
                <button class="btn primary" :disabled="submitting" @click="handleSubmit">提交</button>
                <button class="btn" @click="handleCancel">取消</button>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue'
import { uploadFile, uploadFileWithProgress } from '@/utils/fileUpload'
import { useRouter } from 'vue-router'
import { read, write } from '@/assets/Axios/axiosHttple'

interface CreateVehicleDto {
    brandModel: string
    plateNumber: string
    vehicleType: string
    driverName: string
    company: string
    sizeLength: string
    sizeWidth: string
    sizeHeight: string
    color: string
    purchaseDate: string
    operationCert: string
    insuranceExpire: string
    annualInspectExpire: string
    maintenanceKm: string
}

const form = reactive<CreateVehicleDto>({
    brandModel: '',
    plateNumber: '',
    vehicleType: '',
    driverName: '',
    company: '',
    sizeLength: '',
    sizeWidth: '',
    sizeHeight: '',
    color: '',
    purchaseDate: '',
    operationCert: '',
    insuranceExpire: '',
    annualInspectExpire: '',
    maintenanceKm: ''
})

const submitting = ref(false)
const vehicleInput = ref<HTMLInputElement | null>(null)
const insureInput = ref<HTMLInputElement | null>(null)
const vehiclePreview = ref<string>('')
const insurePreview = ref<string>('')
const vehicleFile = ref<File | null>(null)
const insureFile = ref<File | null>(null)
const vehicleUploadPercent = ref(0)
const insureUploadPercent = ref(0)
const vehicleUploadState = ref<'idle' | 'uploading' | 'success' | 'failed'>('idle')
const insureUploadState = ref<'idle' | 'uploading' | 'success' | 'failed'>('idle')
const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB
const router = useRouter()

// 货主/司机下拉（来源：CargoOwner）
type Owner = { id: number; ownerName: string; unitName?: string }
const ownerOptions = ref<Owner[]>([])
const companyOptions = ref<string[]>([])

async function loadOwners() {
    try {
        const res = await read.get('baseinforead/api/CargoOwner/GetCargoOwnerList', { params: { PageIndex: 1, PageSize: 2000 } })
        let json: any = res?.data ?? { data: [] }
        const list = Array.isArray(json?.data?.data) ? json.data.data : (Array.isArray(json?.data) ? json.data : [])
        ownerOptions.value = (list || []).map((x: any) => ({ id: Number(x.Id ?? x.id ?? x.OwnerId ?? x.ownerId), ownerName: x.ownerName ?? x.OwnerName ?? x.name ?? '', unitName: x.unitName ?? x.UnitName ?? '' }))
    } catch (e) {
        console.error('加载货主列表失败', e)
        ownerOptions.value = []
    }
}

function onDriverChange() {
    const hit = ownerOptions.value.find(o => o.ownerName === form.driverName)
    companyOptions.value = []
    if (hit && hit.unitName) {
        companyOptions.value = [hit.unitName]
        form.company = hit.unitName
    } else if (!form.company) {
        form.company = ''
    }
}

function validate(): string | null {
    if (!form.brandModel) return '请输入厂牌型号'
    if (!form.plateNumber) return '请输入车牌号'
    if (!form.vehicleType) return '请选择车辆类型'
    if (!form.driverName) return '请输入司机姓名'
    if (!form.company) return '请输入所属公司'
    if (!form.sizeLength || !form.sizeWidth || !form.sizeHeight) return '请输入车型长宽高'
    if (!form.purchaseDate) return '请选择购置日期'
    if (!form.operationCert) return '请输入营运证号'
    if (!form.insuranceExpire) return '请选择保险到期日期'
    if (!form.annualInspectExpire) return '请选择年检到期日期'
    return null
}

function onVehicleImg(e: Event) {
    const file = (e.target as HTMLInputElement).files?.[0]
    if (!file) return
    // 校验类型与大小
    if (!file.type.startsWith('image/')) { alert('仅支持图片文件'); return }
    if (file.size > MAX_FILE_SIZE) { alert('图片不能大于5MB'); return }
    vehicleFile.value = file
    const reader = new FileReader()
    reader.onload = () => { vehiclePreview.value = String(reader.result || '') }
    reader.readAsDataURL(file)
}

function onInsureImg(e: Event) {
    const file = (e.target as HTMLInputElement).files?.[0]
    if (!file) return
    if (!file.type.startsWith('image/')) { alert('仅支持图片文件'); return }
    if (file.size > MAX_FILE_SIZE) { alert('图片不能大于5MB'); return }
    insureFile.value = file
    const reader = new FileReader()
    reader.onload = () => { insurePreview.value = String(reader.result || '') }
    reader.readAsDataURL(file)
}

function triggerVehicleInput() {
    if (vehicleInput.value) vehicleInput.value.click()
}

function triggerInsureInput() {
    if (insureInput.value) insureInput.value.click()
}

async function retryVehicleUpload() {
    if (!vehicleFile.value) { alert('无可重试的文件'); return }
    vehicleUploadState.value = 'uploading'
    vehicleUploadPercent.value = 0
    try {
        const url = await uploadFileWithProgress(vehicleFile.value, (pct) => vehicleUploadPercent.value = pct)
        vehicleUploadState.value = 'success'
        // 将上传成功的url写入preview替代base64，便于提交时使用
        vehiclePreview.value = url
    } catch (e: any) {
        console.error('重试上传车辆图片失败', e)
        vehicleUploadState.value = 'failed'
        alert('车辆图片上传失败：' + (e?.message || e))
    }
}

async function retryInsureUpload() {
    if (!insureFile.value) { alert('无可重试的文件'); return }
    insureUploadState.value = 'uploading'
    insureUploadPercent.value = 0
    try {
        const url = await uploadFileWithProgress(insureFile.value, (pct) => insureUploadPercent.value = pct)
        insureUploadState.value = 'success'
        insurePreview.value = url
    } catch (e: any) {
        console.error('重试上传保险卡图片失败', e)
        insureUploadState.value = 'failed'
        alert('保险卡图片上传失败：' + (e?.message || e))
    }
}

async function handleSubmit() {
    const msg = validate()
    if (msg) { alert(msg); return }
    submitting.value = true
    try {
        const toIso = (d: string) => d ? new Date(`${d}T00:00:00`).toISOString() : ''
        const stripDataUrl = (s: string) => s ? (s.includes(',') ? s.split(',')[1] : s) : ''
        // 先上传图片到七牛（若有），失败不阻止提交但会提示
        let vehicleUrl = ''
        let insureUrl = ''
        try {
            if (vehicleFile.value) {
                vehicleUploadState.value = 'uploading'
                vehicleUploadPercent.value = 0
                try {
                    vehicleUrl = await uploadFileWithProgress(vehicleFile.value, (pct) => vehicleUploadPercent.value = pct)
                    vehicleUploadState.value = 'success'
                } catch (e) {
                    vehicleUploadState.value = 'failed'
                    throw e
                }
            }
        } catch (e: any) {
            console.error('车辆图片上传失败', e)
            alert('车辆图片上传失败：' + (e?.message || e))
        }
        try {
            if (insureFile.value) {
                insureUploadState.value = 'uploading'
                insureUploadPercent.value = 0
                try {
                    insureUrl = await uploadFileWithProgress(insureFile.value, (pct) => insureUploadPercent.value = pct)
                    insureUploadState.value = 'success'
                } catch (e) {
                    insureUploadState.value = 'failed'
                    throw e
                }
            }
        } catch (e: any) {
            console.error('保险卡图片上传失败', e)
            alert('保险卡图片上传失败：' + (e?.message || e))
        }
        const payload = {
            brandandModel: String(form.brandModel || ''),
            licensePlateNumber: String(form.plateNumber || ''),
            ownerName: String(form.driverName || ''),
            unitName: String(form.company || ''),
            vehicleType: String(form.vehicleType || ''),
            vehicleColor: String(form.color || ''),
            purchaseDate: toIso(form.purchaseDate),
            long: String(form.sizeLength || ''),
            ratedLoadCapacity: Number(form.maintenanceKm) || 0,
            width: String(form.sizeWidth || ''),
            height: String(form.sizeHeight || ''),
            insuranceExpirationDate: toIso(form.insuranceExpire),
            volume: 0,
            operationCertificateNumber: Number(form.operationCert) || 0,
            annualInspectionExpirationDate: toIso(form.annualInspectExpire),
            maintenanceMileageSetting: Number(form.maintenanceKm) || 0,
            vehicleStatus: true,
            vehiclePhotos: vehicleUrl || stripDataUrl(vehiclePreview.value || ''),
            insuranceCardPhotos: insureUrl || stripDataUrl(insurePreview.value || ''),
            locationInformationStatus: true,
            createdBy: '张三'
        }
        // 尝试提交：先直接提交，若后端要求包裹在 request 下或字段类型不匹配则做兼容重试
        async function doPost(body: any) {
            const res = await write.post('baseinfowrite/api/VehicleManagement/Create', body)
            const json: any = res?.data ?? { code: res?.status }
            return { res, json }
        }

        // 方便地检测错误信息里是否包含某些关键词
        const containsErrorKey = (json: any, keyFragment: string) => {
            if (!json || !json.errors) return false
            try {
                const keys = Object.keys(json.errors)
                return keys.some(k => k.indexOf(keyFragment) >= 0) || JSON.stringify(json.errors).indexOf(keyFragment) >= 0
            } catch { return false }
        }

        // 兼容性尝试：构造若干候选请求体（不同字段命名 / 包裹形式），依次尝试直到成功或全部失败
        function pascalizeKeys(obj: any) {
            if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return obj
            const out: any = {}
            for (const k of Object.keys(obj)) {
                const v = obj[k]
                const newKey = k.charAt(0).toUpperCase() + k.slice(1)
                out[newKey] = pascalizeKeys(v)
            }
            return out
        }

        const candidates: any[] = []
        // 原始
        candidates.push({ ...payload })
        // PascalCase keys
        candidates.push(pascalizeKeys(payload))
        // 包裹在 request/Request
        candidates.push({ request: { ...payload } })
        candidates.push({ Request: { ...payload } })
        candidates.push({ request: pascalizeKeys(payload) })
        candidates.push({ Request: pascalizeKeys(payload) })
        // 如果 operationCertificateNumber 可能导致类型错误，准备移除该字段的备用体
        const payloadNoOp = { ...payload }
        if ((payloadNoOp as any).operationCertificateNumber !== undefined) delete (payloadNoOp as any).operationCertificateNumber;
        (payloadNoOp as any).operationCert = String(form.operationCert || '')
        candidates.push(payloadNoOp)
        candidates.push(pascalizeKeys(payloadNoOp))

        let finalResult: any = null
        for (const bodyCandidate of candidates) {
            try {
                const attempt = await doPost(bodyCandidate)
                finalResult = attempt
                if (attempt.json?.code === 200 || attempt.res.status === 200 || attempt.res.status === 201) {
                    break
                }
                // 若返回 errors 中提到具体必填字段，继续尝试下一个候选体
            } catch (e) {
                console.warn('尝试候选体时出错，继续下一个', e)
            }
        }

        // 处理最终结果
        if (finalResult && finalResult.res && (finalResult.json?.code === 200 || finalResult.res.status === 200 || finalResult.res.status === 201)) {
            router.push('/GetVehicleManagement?refresh=1')
        } else {
            console.error('新增车辆失败', finalResult?.json || finalResult)
            const serverErr = finalResult?.json?.errors ? JSON.stringify(finalResult.json.errors) : (finalResult?.json?.message || JSON.stringify(finalResult?.json) || null)
            alert(serverErr || '新增车辆失败，详情请查看控制台')
        }
    } finally {
        submitting.value = false
    }
}

function handleCancel() { if (window.history.length > 1) window.history.back() }

// 初始化
loadOwners()
</script>

<style scoped>
.vehicle-add-page {
    padding: 16px 20px;
    color: #333;
    font-size: 14px;
}

.page-title {
    font-size: 18px;
    margin-bottom: 12px;
}

.card {
    background: #fff;
    border: 1px solid #e5e6eb;
    border-radius: 4px;
}

.form {
    padding: 16px;
}

.grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(320px, 1fr));
    gap: 12px 24px;
    align-items: start;
    max-width: 1100px;
}

.form-item {
    display: flex;
    align-items: center;
}

.form-item.required .label::before {
    content: '*';
    color: #f56c6c;
    margin-right: 4px;
}

.label {
    width: 120px;
    color: #666;
}

.input {
    flex: 1;
    height: 32px;
    line-height: 32px;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    padding: 0 10px;
}

.size-group .size {
    width: 80px;
    margin-right: 8px;
}

.upload-item {
    align-items: center;
}

.upload-box {
    width: 210px;
    height: 160px;
    border: 1px dashed #dcdfe6;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    position: relative;
    background: #fafafa;
}

.file-input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.uploader {
    text-align: center;
    color: #909399;
}

.plus {
    font-size: 36px;
    line-height: 1;
}

.preview {
    max-width: 100%;
    max-height: 100%;
    border-radius: 4px;
}

.form-actions {
    margin-top: 18px;
    display: flex;
    gap: 10px;
}

.btn {
    height: 32px;
    padding: 0 16px;
    border: 1px solid #dcdfe6;
    background: #fff;
    border-radius: 4px;
    cursor: pointer;
}

.btn.primary {
    background: #409eff;
    border-color: #409eff;
    color: #fff;
}

.btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}
</style>
